package com.jeesite.modules.codingrule.service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.ServiceException;
import com.jeesite.common.utils.OrgUtil;
import com.jeesite.modules.billconfig.entity.BillConfig;
import com.jeesite.modules.codingrule.entity.qo.CodingRuleQO;
import com.jeesite.modules.codingrule.entity.vo.CodingRuleVO;
import com.jeesite.modules.codingrule.enums.CodingTypeEnum;
import com.jeesite.modules.codingrule.enums.ObjectTypeEnum;
import com.jeesite.modules.codingrule.enums.SeparatorEnum;
import com.jeesite.modules.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jeesite.common.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.codingrule.entity.CodingRuleHeader;
import com.jeesite.modules.codingrule.dao.CodingRuleHeaderDao;
import com.jeesite.modules.codingrule.entity.CodingRuleLines;
import com.jeesite.modules.codingrule.dao.CodingRuleLinesDao;

/**
 * 编码规则Service
 * @author 码脑洞
 * @version 2025-04-13
 */
@Service
public class CodingRuleHeaderService extends CrudService<CodingRuleHeaderDao, CodingRuleHeader> {
	
	@Autowired
	private CodingRuleLinesDao codingRuleLinesDao;
	
	/**
	 * 获取单条数据
	 * @param codingRuleHeader
	 * @return
	 */
	@Override
	public CodingRuleHeader get(CodingRuleHeader codingRuleHeader) {
		CodingRuleHeader entity = super.get(codingRuleHeader);
		if (entity != null){
			CodingRuleLines codingRuleLines = new CodingRuleLines(entity);
			codingRuleLines.setStatus(CodingRuleLines.STATUS_NORMAL);
			entity.setLinesList(codingRuleLinesDao.findList(codingRuleLines));
		}
		return entity;
	}
	
	/**
	 * 查询分页数据
	 * @param codingRuleHeader 查询条件
	 * @param codingRuleHeader page 分页对象
	 * @return
	 */
	@Override
	public Page<CodingRuleHeader> findPage(CodingRuleHeader codingRuleHeader) {
		return super.findPage(codingRuleHeader);
	}
	
	/**
	 * 查询列表数据
	 * @param codingRuleHeader
	 * @return
	 */
	@Override
	public List<CodingRuleHeader> findList(CodingRuleHeader codingRuleHeader) {
		return super.findList(codingRuleHeader);
	}
	
	/**
	 * 查询子表分页数据
	 * @param codingRuleLines
	 * @param codingRuleLines page 分页对象
	 * @return
	 */
	public Page<CodingRuleLines> findSubPage(CodingRuleLines codingRuleLines) {
		Page<CodingRuleLines> page = codingRuleLines.getPage();
		page.setList(codingRuleLinesDao.findList(codingRuleLines));
		return page;
	}

	@Override
	public void preSave(CodingRuleHeader codingRuleHeader) {
		//TODO 保存前的业务代码
		Date currentDate = new Date();
		if (codingRuleHeader.getIsNewRecord()){
			codingRuleHeader.setCreateBy(UserUtils.getUser().getCreateBy());
			codingRuleHeader.setCreateDate(currentDate);
		}
		codingRuleHeader.setUpdateBy(UserUtils.getUser().getCreateBy());
		codingRuleHeader.setUpdateDate(currentDate);
	}

	/**
	 * 设置编码示例值
	 * @param codingRuleHeader 编码规则头信息
	 * @return 生成的编码示例值
	 */
	public String generateExampleCode(CodingRuleHeader codingRuleHeader) {
		if (codingRuleHeader == null || codingRuleHeader.getLinesList() == null) {
			throw new ServiceException("编码规则头信息或行明细不能为空");
		}
		// 获取当前日期时间
		LocalDateTime now = LocalDateTime.now();
		StringBuilder codingDesc = new StringBuilder();
		for (CodingRuleLines line : codingRuleHeader.getLinesList()) {
			if (!CodingRuleLines.STATUS_DELETE.equals(line.getStatus())) {
				// 根据行明细的类型生成示例值
				String codingType = line.getCodingType();
				switch (codingType) {
					case "1":
						String codingValue = line.getCodingValue();
						codingDesc.append(codingValue);
						break;
					case "2":
						String beginValue = line.getBeginValue();
						codingDesc.append(beginValue);
						break;
					case "3":
						// 从当前日期时间中获取年份
						int currentYear = now.getYear();
						codingDesc.append(currentYear);
						break;
					case "4":
						// 获取当前年份
						int year = now.getYear();
						// 获取当前年份的后两位
						int shortYear = year % 100;
						codingDesc.append(shortYear);
						break;
					case "5":
						// 获取当前月份
						int month = now.getMonthValue();
						// 如果月份小于10，在前面添加0以确保它是两位数
						String shortMonth = (month < 10) ? "0" + month : String.valueOf(month);

						codingDesc.append(shortMonth);
						break;
					case "6":
						// 获取当前日
						int day = now.getDayOfMonth();
						// 如果日期小于10，在前面添加0以确保它是两位数
						String shortDay = (day < 10) ? "0" + day : String.valueOf(day);

						codingDesc.append(shortDay);
						break;
				}
				// 分隔符
				if (StringUtils.isNotBlank(line.getSeparator())) {
					String value = SeparatorEnum.getCode(line.getSeparator());
					codingDesc.append(value);
				}

			}
		}
		return codingDesc.toString();
	}

	/**
	 * 保存数据（插入或更新）
	 * @param codingRuleHeader
	 */
	@Override
	@Transactional
	public void save(CodingRuleHeader codingRuleHeader) {
		// 校验必填字段
		if (ObjectTypeEnum.BILL.getCode().equals(codingRuleHeader.getObjectType()) && codingRuleHeader.getFormId() == null) {
			throw new ServiceException("当对象类型是单据时，表单名称必填");
		}
		if (ObjectTypeEnum.BARCODE.getCode().equals(codingRuleHeader.getObjectType()) && codingRuleHeader.getBarcodeType() == null) {
			throw new ServiceException("当对象类型是条码时，条码类型必填");
		}

		String codingDesc = generateExampleCode(codingRuleHeader);
		codingRuleHeader.setCodingDesc(codingDesc);

		super.save(codingRuleHeader);

		// 保存 CodingRuleHeader子表
		int sequence = 10; // 序号从 10 开始
		for (CodingRuleLines codingRuleLines : codingRuleHeader.getLinesList()){
			if (!CodingRuleLines.STATUS_DELETE.equals(codingRuleLines.getStatus())){
				codingRuleLines.setHeaderId(codingRuleHeader);
				codingRuleLines.setSeq(sequence); // 设置序号
				sequence += 10; // 每次递增 10
				if (codingRuleLines.getIsNewRecord()){
					codingRuleLinesDao.insert(codingRuleLines);
				}else{
					codingRuleLinesDao.update(codingRuleLines);
				}
			}else{
				codingRuleLinesDao.delete(codingRuleLines);
			}
		}
	}
	
	/**
	 * 更新状态
	 * @param codingRuleHeader
	 */
	@Override
	@Transactional
	public void updateStatus(CodingRuleHeader codingRuleHeader) {
		super.updateStatus(codingRuleHeader);
	}
	
	/**
	 * 删除数据
	 * @param codingRuleHeader
	 */
	@Override
	@Transactional
	public void delete(CodingRuleHeader codingRuleHeader) {
		super.delete(codingRuleHeader);
		CodingRuleLines codingRuleLines = new CodingRuleLines();
		codingRuleLines.setHeaderId(codingRuleHeader);
		codingRuleLinesDao.deleteByEntity(codingRuleLines);
	}

	public Page<CodingRuleVO> findCodingRulePage(CodingRuleQO codingRuleQO) {
		Page<CodingRuleVO> page = codingRuleQO.getPage();
		codingRuleQO.setOrgId(OrgUtil.getOrgId());
		page.setList(dao.findCodingRulePage(codingRuleQO));
		return page;
	}

	public boolean isAutoGenned(long orgId, String formCode) {
		Integer codingType = dao.getCodingType(orgId, formCode);
		return Objects.equals(CodingTypeEnum.MANUAL.getCode(), codingType);
	}

	public CodingRuleHeader getCodingRuleHeader(long orgId, String billTypeSn, String barcodeType, long sourceId) {
		return dao.getCodingRuleHeader(orgId, billTypeSn, barcodeType, sourceId);
	}

	public List<CodingRuleLines> getListOrderBySeq(Long headerId) {
		return codingRuleLinesDao.getListOrderBySeq(headerId);
	}
}